package DockerOperation;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(init_config);

use JSON::RPC::Client;
use Data::Dumper;
use LWP::UserAgent;
use JSON;

#实例初始化
sub new
{
    my $class = shift;
    my $self = shift;
    my %parm = @_;

    print "\n /* \n ** Urfresh Docker Manage Tool \n */\n\n";
    
    bless($self,$class);
    $self->init;

    return $self;
}

#获取base_url
sub init
{
    my $self = shift;
    my $base_url = $self->{'base_url'} or die "No Base Url Given!\n";
}


# 所有的GET操作初始化
sub _Http_Get
{
    my $self = shift;
    my $uri = shift;
    my $base_url = $self->{'base_url'};

    my $full_url = $base_url.$uri;

    my $json_res;
    my $json = new JSON;
    
    #创建LWP实例
    my $ua = LWP::UserAgent->new;
    $ua->agent("Line0/1.0");

    #创建一个请求
    my $req = HTTP::Request->new("GET" => "$full_url");
    
    #
    my $res = $ua->request($req);


    #检查响应的结果,如果有错误，则直接返回undef
    if($res->is_success){
	$json_res = $res->content;
    }else{
	print $res->status_line, "\n";
	return undef;
    }


    my $obj = $json->decode($json_res);

    #print Dumper($obj);

    return $obj;
    
}


sub _Http_Post
{
    my $self = shift;    
    #my $uri = shift;
    #my $json = shift;
    my ($uri,$post_json) = @_;
    
    my $base_url = $self->{'base_url'}; 
    my $full_url = $base_url.$uri;

    #print "\$full_url = $full_url\n";
    
    my $json = new JSON;
    
    #创建LWP实例
    my $ua = LWP::UserAgent->new;
    $ua->agent("Line0 DockerOP/1.0");
    
    my $req = HTTP::Request->new("POST" => "$full_url");

    #如果有json需要POST
    if($post_json){
	$post_json = $json->encode($post_json);
	$req->content_type("Content-Type: application/json");
	#$req->content_type("\'application/json\'");
	$req->content("query=$post_json");
	#$ua->post($full_url,$post_json);
    }
    
    
    # Pass request to the user agent and get a response back
    my $res = $ua->request($req);

    return $res;


}

#删除
sub _Http_Delete
{
    my $self = shift;    
    my $uri = shift;
    
    my $base_url = $self->{'base_url'}; 
    my $full_url = $base_url.$uri;

   
    #创建LWP实例
    my $ua = LWP::UserAgent->new;
    $ua->agent("Line0 DockerOP/1.0");
    
    my $req = HTTP::Request->new("DELETE" => "$full_url");
    
    # Pass request to the user agent and get a response back
    my $res = $ua->request($req);

    return $res;


}

#需要推送JSON的POST操作
sub _Http_Post_Json
{
    my $self = shift;
    my $uri = shift;
    my $json = shift;

    my $client = new JSON::RPC::Client;
    
    my $base_url = $self->{'base_url'};
    my $full_url = $base_url.$uri;
    print $full_url."\n";
       
    my $res = $client->call($full_url,$json);

    #print Dumper($res);
   
    return $res;
    
}


#获取所有容器列表
sub _Container_List
{
    my $self = shift;
    #----$status的值为0 1 2-------
    # 0: 状态为up的容器列表,默认值
    # 1: 所有的容器列表，包括Exit、Created状态的
    my $status = shift;

    #如果没有值传递，就赋予默认值
    $status = 0 if(!$status);
    
    my $uri = "/containers/json?all=$status";

    my $ret = $self->_Http_Get("$uri");
    
    return $ret;        
}



#通过ID或者name获取容器信息
sub _Container_info_by_id_name_ref
{
    my $self = shift;
    my $name = shift;
    my $container_array_ref = $self->_Container_List;
    my $info_ref = undef;

   
    #对比每个容器的ID或者NAME
    foreach my $array_ref (@$container_array_ref){
	

	#如果Id可以匹配
	if($array_ref->{'Id'} =~ $name){
	    $info_ref = $array_ref;
	    last;
	}

	#如果Id不能匹配，使用name进行匹配，在name前需加/
	$name = '/'.$name;
	if($array_ref->{'Names'}[0] =~ $name){
	    $info_ref = $array_ref;
	    last;
	}
	
    }

    #print Dumper($info_ref);
    
    return $info_ref
    
}


#获取通过某个image启动的容器
sub _Container_info_with_image_ref
{
    my $self = shift;
    my $name = shift;

    my $container_array_ref = $self->_Container_List;
    my @info_ref;


    #对比每个image的ID或NAME
    foreach my $array_ref (@$container_array_ref){
	if( ($array_ref->{'Image'} =~ $name) || ($array_ref->{'ImageID'} =~ $name) ){
	    #$info_ref = $array_ref;
	    #last;
	    push(@info_ref,$array_ref);
	}
    }
    
    return \@info_ref;
}

#创建容器--原生接口
sub _Create_Container_Native
{
    my $self = shift;
    my $json = shift;

    #print Dumper($json);

    my $uri = '/containers/create';

    #my $base_url = $self->{'base_url'};
    
    my $ret = $self->_Http_Post_Json($uri,$json);
    
    return $ret;
}



#获取容器底层信息
sub _Inspect_Container
{
    my $self = shift;
    my $cid =  shift;
    my $uri = "/containers/$cid/json";
    my $ret =  $self->_Http_Get($uri);

    return $ret;
}


#创建一个exec instance,并返回id
sub _Exec_Create
{

    my $self = shift;
    my ($cid,$json) = @_;


    if(!$cid)
    {
        print "_Exec_Create() Error: Container id or name is NULL!\n";
        exit;
    }

    my $uri = "/containers/$cid/exec";
        
    my $ret = $self->_Http_Post_Json($uri,$json);
    
    return $ret;
}


#执行设置的exec instance
sub _Exec_Start
{
    my $self = shift;
    my $exec_instance_id = shift;

    my $json = {
	Detach => false,
	Tty =>false
    };

    my $uri = "/exec/$exec_instance_id/start";
    #print "$uri"."\n";

    my $ret = $self->_Http_Post_Json($uri,$json);

    return $ret;
    
}

# _Start_Stop_Kill_Restart_Contaner($cid,"start|stop|restart")
sub _Start_Stop_Kill_Restart_Contaner
{
    my $self = shift;
    my ($cid,$operation,$t) = @_;


    #默认不等待
    $t =0 if(!$t);
    
    #t=5表示等待5s
    my $uri = "/containers/$cid/$operation?t=$t";

    #print $uri."\n";
    
    my $ret = $self->_Http_Post($uri);

    return $ret;
}


sub _Rename_Container
{
    my $self = shift;
    my ($cid,$new_name) = @_;

    my $uri = "/containers/$cid/rename?name=$new_name";

    my $ret = $self->_Http_Post($uri);

    return $ret;
}


sub _Remove_Container
{
    my $self = shift;
    #cid有可能是name也有可能是ID
    my $cid = shift;

    print "\$cid = $cid\n";

    my $uri = "/containers/$cid?v=1";
    my $ret = $self->_Http_Delete($uri);

    return $ret;
}


sub _Attach_To_Container
{
    my $self = shift;
    my $cid = shift;


    my $uri = "/containers/$cid/attach?logs=1&stream=0&stdout=1";

    my $ret = $self->_Http_Post($uri);

    return $ret;
}



1;
